package com.qf.index;

import cn.hutool.core.io.FileUtil;
import cn.hutool.core.util.NumberUtil;
import cn.hutool.db.Db;
import cn.hutool.db.Entity;
import cn.hutool.json.JSONUtil;
import com.alibaba.fastjson.JSONObject;
import lombok.Data;
import org.springframework.expression.EvaluationException;
import org.springframework.expression.Expression;
import org.springframework.expression.ExpressionParser;
import org.springframework.expression.spel.standard.SpelExpressionParser;

import java.io.File;
import java.io.Serializable;
import java.sql.SQLException;
import java.time.LocalDateTime;
import java.util.*;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

public class Institution {

    /**
     * 此程序的功能是，对于从WOS下载的CSV数据，区分第一或通讯作者单位，并可以区分出来医学院校和附属医院的数据。
     * 贾新志 2025.02.06
     */
    public static void main(String[] args) throws SQLException {
        String csvWosTable = "scholar_25_02.csv_wos_talbe";
        String jourMergeTable = "scholar_25_02.basic_jour_merge";
        Db.use().execute("truncate table " + csvWosTable);

        // 先把本次要更新的插入新表，新表为一张新建的空表。需要将检索的单位下载的CSV格式的WOS的数据的文件目录作为参数带入方法中，文件目录内不能有其它单位的数据。
//        String filePath = "C:\\临时文件\\2025_03\\qfs";
//        String filePath = "C:\\临时文件\\2025_03\\Tianjin";
//        String filePath = "C:\\临时文件\\2025_03\\盛京";
//        String filePath = "C:\\临时文件\\2025_03\\医大一";
        String filePath = "C:\\临时文件\\2025_03\\天津医大";
//        String filePath = "C:\\临时文件\\2025_03\\沈阳药科大学";
        List<InsertInfo> insertInfoList = saveCsvSplitWos(csvWosTable, filePath, 123, 1);
        for (InsertInfo insertInfo : insertInfoList) {
            System.out.println(insertInfo);
        }

        // 计算校本部和指定的附属医院，第一或通讯作者的发文数量，univSet和hospSet是用户的设置，表示包含该词的文本信息是属于大学或医院，hospPriority是优先设置，当文本中同时包含大学和医院时，默认医院优先（即true），否则大学优先。
//        String kw = "AD=((Shandong First Med Univ) SAME (Affiliated Hosp 1 OR Hosp Affiliated 1) SAME (Jinan OR 250014)) OR AD=(Qianfoshan Hosp)";
//        String kw = "AD=((Chinese Acad Med Sci OR CAMS OR Peking Union Med Coll) SAME (Hosp Blood Dis OR Blood Dis Hosp OR Natl Clin Res Ctr Blood Dis))";
//        String kw = "AD=((China Med Univ) SAME (Shengjing Hosp OR Hosp 2 OR Sheng Jing Hosp OR Shengjing Affiliated Hosp OR Shenjing Hosp) SAME (Shenyang OR Shen yang OR 110022 OR China OR Liaoning))";
//        String kw = "AD=((China Med Univ OR Chinese Med Univ) SAME (Hosp 1 OR First Hosp) SAME (Shenyang OR Shen yang OR China OR Liaoning)) OR AD=(1 Hosp China Med Univ)";
        String kw = "AD=(Tianjin Med Univ) OR AD=(Tianjin Med Coll) OR AD=(Tian Jin Med Univ)";
//        String kw = "AD=(Shenyang Pharmaceut Univ) OR AD=(SHENYANG COLL PHARM) OR AD=(Shen Yang Pharmaceut Univ) OR AD=(Shengyang Pharmaceut Univ)";
        Set<String> univSet = new HashSet<>();
        univSet.add(" univ");
        univSet.add("univ ");
        univSet.add("sch med");
        univSet.add("coll med");
        univSet.add("med coll");

        Set<String> hospSet = new HashSet<>();
        hospSet.add(" hosp");
        hospSet.add("hosp ");
        hospSet.add("affiliated");
        boolean hospPriority = true;

        // 更新表，在展示界面，用户可以选择c1（全部、第一）、rp(全部、第一)、c1与rp的关系（and、or）、机构选择（全部、仅校本部、仅医院）、影响因子范围（可选if也可选cs）、分区（可选中科院也可选JCR）、预警期刊（全部、预警）
        updateTable(csvWosTable, kw, 123, 1, univSet, hospSet, hospPriority, jourMergeTable);


    }

    public static void updateTable(String csvWosTable, String kw, int userId, int sort, Set<String> univSet, Set<String> hospSet, boolean hospPriority, String jourMergeTable) throws SQLException {
        List<Entity> tableData = Db.use().query("select `pid`,`C1`,`RP`,`J9`,`SO`,`PY`,`SN`,`EI`,`PM`,`UT` from " + csvWosTable + " where user_id = " + userId + " AND sort =  " + sort);

        Map<String, JidInfo> zuHeAndJidInfoMap = getZuHeAndJidInfoMap(jourMergeTable, "id", "jcr_quartile`,`zky_subject`,`cite_score`,`jcr_if`,`zky_dalei`,`zuhe");

        Set<String> early2020 = getEarly2020();
        Set<String> early2021 = getEarly2021();
        Set<String> early2023 = getEarly2023();
        Set<String> early2024 = getEarly2024();
        int sum = 0;
        Set<String> utSet = new HashSet<>();
        for (Entity entry : tableData) {
            int pid = getIntField(entry, "pid");
            List<C1Auth> c1List = getC1List(entry.getStr("C1"));
            List<C1Auth> rpList = getRpList(entry.getStr("RP"));
            List<SortInfo> c1SortInfoList = addSortInfoList(c1List, kw, univSet, hospSet, hospPriority);
            List<SortInfo> rpSortInfoList = addSortInfoList(rpList, kw, univSet, hospSet, hospPriority);
            int c1 = 0;
            int c1Univ = 0;
            int c1Hosp = 0;
            for (SortInfo sortInfo : c1SortInfoList) {
                int order = sortInfo.getOrder();
                if (order == 0) {
                    c1 = 1;
                    c1Univ = sortInfo.univ ? 1 : c1Univ;
                    c1Hosp = sortInfo.hosp ? 1 : c1Hosp;
                } else {
                    c1 = c1 == 0 ? 2 : c1;
                    c1Univ = sortInfo.univ && c1Univ == 0 ? 2 : c1Univ;
                    c1Hosp = sortInfo.hosp && c1Hosp == 0 ? 2 : c1Hosp;
                }
            }
            // c1和rp均有三种值，分别是0、1、2，0为不包含，1为第一作者，2为参与作者。c1又分为c1、c1Univ、c1Hosp三种，rp又分为rp、rpUniv、rpHosp三种。
            int rp = 0;
            int rpUniv = 0;
            int rpHosp = 0;
            for (SortInfo sortInfo : rpSortInfoList) {
                int order = sortInfo.getOrder();
                if (order == 0) {
                    rp = 1;
                    rpUniv = sortInfo.univ ? 1 : rpUniv;
                    rpHosp = sortInfo.hosp ? 1 : rpHosp;
                } else {
                    rp = rp == 0 ? 2 : rp;
                    rpUniv = sortInfo.univ && rpUniv == 0 ? 2 : rpUniv;
                    rpHosp = sortInfo.hosp && rpHosp == 0 ? 2 : rpHosp;
                }
            }

            // 计算预警期刊以及期刊的影响因子和分区等。
            String j9 = getStrField(entry, "J9").toUpperCase();
            String so = getStrField(entry, "SO").toUpperCase();
            String py = getStrField(entry, "PY");
            int isEarly = 0;
            if ("2020".equals(py) && (early2020.contains(j9) || early2020.contains(so))) {
                isEarly = 1;
            } else if ("2021".equals(py) && (early2021.contains(j9) || early2021.contains(so))) {
                isEarly = 1;
            } else if ("2023".equals(py) && (early2023.contains(j9) || early2023.contains(so))) {
                isEarly = 1;
            } else if ("2024".equals(py) && (early2024.contains(j9) || early2024.contains(so))) {
                isEarly = 1;
            }
            String sn = getStrField(entry, "SN");
            String ei = getStrField(entry, "EI");
            JidInfo jidInfo = new JidInfo();
            if (!sn.isEmpty() && !j9.isEmpty() && zuHeAndJidInfoMap.containsKey(re("ISSN" + sn + j9))) {
                jidInfo = zuHeAndJidInfoMap.get(re("ISSN" + sn + j9));
            } else if (!sn.isEmpty() && !so.isEmpty() && zuHeAndJidInfoMap.containsKey(re("ISSN" + sn + so))) {
                jidInfo = zuHeAndJidInfoMap.get(re("ISSN" + sn + so));
            } else if (!ei.isEmpty() && !j9.isEmpty() && zuHeAndJidInfoMap.containsKey(re("ISSN" + ei + j9))) {
                jidInfo = zuHeAndJidInfoMap.get(re("ISSN" + ei + j9));
            } else if (!ei.isEmpty() && !so.isEmpty() && zuHeAndJidInfoMap.containsKey(re("ISSN" + ei + so))) {
                jidInfo = zuHeAndJidInfoMap.get(re("ISSN" + ei + so));
            }
            try {
                Db.use().update(
                        Entity.create().set("c1_code", c1).set("c1_univ_code", c1Univ).set("c1_hosp_code", c1Hosp).set("rp_code", rp).set("rp_univ_code", rpUniv).set("rp_hosp_code", rpHosp).set("datetime", LocalDateTime.now())
                                .set("is_early", isEarly).set("jcr_quartile", jidInfo.getJcrQuartile()).set("zky_subject", jidInfo.getZkySubject()).set("cite_score", jidInfo.getCiteScore()).set("jcr_if", jidInfo.getJcrIf()).set("zky_dalei", jidInfo.getZkyDaLei())
                                .set("univ_name", JSONUtil.toJsonStr(univSet)).set("hosp_name", JSONUtil.toJsonStr(hospSet)).set("c1_list", JSONUtil.toJsonStr(c1SortInfoList)).set("rp_list", JSONUtil.toJsonStr(rpSortInfoList)).set("hosp_priority", hospPriority ? 1 : 0),
                        Entity.create(csvWosTable).set("pid", pid));
            } catch (SQLException e) {
                e.printStackTrace();
            }
            String pm = getStrField(entry, "PM");
            String ut = getStrField(entry, "UT");
            double jcrIf = jidInfo.getJcrIf(); // 影响因子
            int zkyDaLei = jidInfo.getZkyDaLei(); // 中科院大类分区
            if ((c1Hosp == 2 || rpHosp == 1) && (zkyDaLei == 1) && (py.equals("2020") || py.equals("2021") || py.equals("2022") || py.equals("2023") || py.equals("2024")) && jcrIf >= 1.3 && jcrIf <= 9.9) {
                sum++;
                utSet.add(ut);
            }
        }
        System.out.println("如果是第一作者，或者是通讯作者，发文总篇数：" + utSet.size() + " utSet:" + utSet);
    }

    public static String re(String str) {
        return str.toUpperCase().replace("-", "").replace(" ", "").trim();
    }

    @Data
    public static class JidInfo implements Serializable {
        private int jcrQuartile = 0; // scie期刊分区
        private String zkySubject = ""; // 中科院大区名称
        private double citeScore = 0.0; // 期刊cite影响因子值
        private double jcrIf = 0.0; // jcr(scie)期刊影响因子
        private int zkyDaLei = 0; // 中科院大类分区最佳值
    }

    public static Map<String, JidInfo> getZuHeAndJidInfoMap(String jourMergeTable, String autoId, String field) throws SQLException {
        int onePageNum = 1000;
        Map<String, JidInfo> zuHeAndJidInfoMap = new HashMap<>();
        int tableMax = Db.use().queryNumber("select max(" + autoId + ") from " + jourMergeTable).intValue();
        if (tableMax > 0) {
            Collection<Integer> tableList = new ArrayList<>();
            NumberUtil.appendRange(0, tableMax + onePageNum, onePageNum, tableList);
            for (Integer startId : tableList) {
                List<Entity> tableData = Db.use().query("select `" + autoId + "`,`" + field + "` from " + jourMergeTable + " where " + autoId + " between " + startId + " and " + (startId + onePageNum - 1));
                for (Entity entry : tableData) {
                    JidInfo jidInfo = new JidInfo();
                    String jcrQuartile = getStrField(entry, "jcr_quartile").toUpperCase().replace("Q", "").replace(" ", "").trim();
                    jidInfo.setJcrQuartile(NumberUtil.isInteger(jcrQuartile) ? Integer.parseInt(jcrQuartile) : 0);
                    jidInfo.setZkySubject(getStrField(entry, "zky_subject"));
                    jidInfo.setCiteScore(getDouField(entry, "cite_score"));
                    jidInfo.setJcrIf(getDouField(entry, "jcr_if"));
                    jidInfo.setZkyDaLei(getIntField(entry, "zky_dalei"));
                    String zuHes = getStrField(entry, "zuhe");
                    if (zuHes.contains("\"]")) {
                        List<String> zuHeList = JSONObject.parseArray(zuHes, String.class);
                        for (String zuHe : zuHeList) {
                            if (zuHe.contains("ISSN")) {
                                zuHeAndJidInfoMap.put(re(zuHe), jidInfo);
                            }
                        }
                    }
                }
            }
        }
        return zuHeAndJidInfoMap;
    }

    @Data
    public static class SortInfo implements Serializable {
        private static final long serialVersionUID = 1L;
        private String info = "";
        private int order = 0;
        private Boolean univ = false;
        private Boolean hosp = false;
    }

    public static List<SortInfo> addSortInfoList(List<C1Auth> c1OrRpList, String kw, Set<String> univSet, Set<String> hospSet, boolean hospPriority) {
        List<SortInfo> sortInfoList = new ArrayList<>();
        for (int i = 0; i < c1OrRpList.size(); i++) {
            String c1OrRp = c1OrRpList.get(i).getInfo().toLowerCase();
            if (doCheck(c1OrRp, checkGrammar(kw))) {
                SortInfo sortInfo = new SortInfo();
                for (String univ : univSet) {
                    if (c1OrRp.contains(univ.toLowerCase()) && univ.length() > 3) {
                        sortInfo.setUniv(true);
                        break;
                    }
                }
                // univSet和hospSet为用户设置的，如果包含某个词即为该类，比如，设置包含"affiliated hosp"即为医院，此设置不区分大小写，但区分前后的空格。
                for (String hosp : hospSet) {
                    if (c1OrRp.contains(hosp.toLowerCase()) && hosp.length() > 3) {
                        sortInfo.setHosp(true);
                        break;
                    }
                }
                // 如果医院优先（hospPriority为true），则大学和医院均匹配到时，要医院，不要大学（大学设为false），否则医院设为false。
                if (sortInfo.hosp && sortInfo.univ) {
                    if (hospPriority) {
                        sortInfo.setUniv(false);
                    } else {
                        sortInfo.setHosp(false);
                    }
                }
                sortInfo.setOrder(i);
                sortInfo.setInfo(c1OrRp);
                sortInfoList.add(sortInfo);
            }
        }
        return sortInfoList;
    }

    public static String getStrField(Entity entry, String field) {
        String str = entry.getStr(field);
        return null == str ? "" : str.trim();
    }

    public static int getIntField(Entity entry, String field) {
        Integer num = entry.getInt(field);
        return null == num ? 0 : num;
    }

    public static double getDouField(Entity entry, String field) {
        Double dou = entry.getDouble(field);
        return null == dou ? 0.0 : dou;
    }

    @Data
    public static class InsertInfo implements Serializable {
        private static final long serialVersionUID = 1L;
        private String filePath = "";
        private int sum = 0;
    }

    public static void insertTable(String csvWosTable, String filePath, Set<String> utSet, List<InsertInfo> insertInfoList, int userId, int sort) {
        String str = FileUtil.readUtf8String(filePath);
        String[] line = str.split("\n");
        int sum = utSet.size();
        for (int i = 1; i < line.length; i++) {
            String[] split = line[i].split("\t");
            if (split.length != 71) {
                continue;
            }
            String ut = split[70].trim().toUpperCase();
            if (!utSet.contains(ut) && ut.startsWith("WOS:") && ut.length() == 19) {
                utSet.add(ut);
                try {
                    Db.use().insert(Entity.create(csvWosTable).set("PT", split[0].trim()).set("AU", split[1].trim()).set("BA", split[2].trim()).set("BE", split[3].trim()).set("GP", split[4].trim()).set("AF", split[5].trim()).set("BF", split[6].trim()).set("CA", split[7].trim()).set("TI", split[8].trim())
                            .set("SO", split[9].trim()).set("SE", split[10].trim()).set("BS", split[11].trim()).set("LA", split[12].trim()).set("DT", split[13].trim()).set("CT", split[14].trim()).set("CY", split[15].trim()).set("CL", split[16].trim()).set("SP", split[17].trim()).set("HO", split[18].trim())
                            .set("DE", split[19].trim()).set("ID", split[20].trim()).set("AB", split[21].trim()).set("C1", split[22].trim()).set("C3", split[23].trim()).set("RP", split[24].trim()).set("EM", split[25].trim()).set("RI", split[26].trim()).set("OI", split[27].trim()).set("FU", split[28].trim())
                            .set("FP", split[29].trim()).set("FX", split[30].trim()).set("CR", split[31].trim()).set("NR", split[32].trim()).set("TC", split[33].trim()).set("Z9", split[34].trim()).set("U1", split[35].trim()).set("U2", split[36].trim()).set("PU", split[37].trim()).set("PI", split[38].trim())
                            .set("PA", split[39].trim()).set("SN", split[40].trim()).set("EI", split[41].trim()).set("BN", split[42].trim()).set("J9", split[43].trim()).set("JI", split[44].trim()).set("PD", split[45].trim()).set("PY", split[46].trim()).set("VL", split[47].trim()).set("IS", split[48].trim())
                            .set("PN", split[49].trim()).set("SU", split[50].trim()).set("SI", split[51].trim()).set("MA", split[52].trim()).set("BP", split[53].trim()).set("EP", split[54].trim()).set("AR", split[55].trim()).set("DI", split[56].trim()).set("DL", split[57].trim()).set("D2", split[58].trim())
                            .set("EA", split[59].trim()).set("PG", split[60].trim()).set("WC", split[61].trim()).set("WE", split[62].trim()).set("SC", split[63].trim()).set("GA", split[64].trim()).set("PM", split[65].trim()).set("OA", split[66].trim()).set("HC", split[67].trim()).set("HP", split[68].trim())
                            .set("DA", split[69].trim()).set("UT", split[70].trim()).set("user_id", userId).set("sort", sort));
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
        }
        InsertInfo insertInfo = new InsertInfo();
        insertInfo.setFilePath(filePath);
        insertInfo.setSum(utSet.size() - sum);
        insertInfoList.add(insertInfo);
    }

    public static List<InsertInfo> saveCsvSplitWos(String csvWosTable, String filePath, int userId, int sort) {
        Set<String> utSet = new HashSet<>();
        List<InsertInfo> insertInfoList = new ArrayList<>();
        List<File> files = FileUtil.loopFiles(filePath);
        for (File file : files) {
            insertTable(csvWosTable, file.getAbsolutePath(), utSet, insertInfoList, userId, sort);
        }
        InsertInfo insertInfo = new InsertInfo();
        insertInfo.setFilePath(filePath);
        insertInfo.setSum(utSet.size());
        insertInfoList.add(insertInfo);
        return insertInfoList;
    }

    public static List<C1Auth> getC1List(String c1s) {
        // 获取C1的单位信息，如果存在重复，给予删除，且仍保留原来的顺序。2024.12.11发现有超长的unit信息，即同一个作者在多个单位，WOS:000978358600001，现已改进。获取C1作者信息，2025.01.14版本。.replace(".;-;", "; ")(样例：000397583000001)
        List<C1Auth> list = new ArrayList<>();
        if (null != c1s && c1s.length() > 6) {
            c1s = c1s.replace("；", "; ").replace(".;-;", "; ").replaceAll(" +", " ").trim();
            String[] split = (c1s.contains("; [") || c1s.contains("] ")) ? c1s.split("; \\[") : c1s.split("; ");
            for (int i = 0; i < split.length; i++) {
                String c1 = split[i];
                String units = c1.indexOf("] ") > 0 ? c1.substring(c1.indexOf("] ") + "] ".length()).trim() : c1.trim();
                units = units.endsWith(".") ? units.substring(0, units.length() - ".".length()).trim() : units.trim();
                String auths = c1.indexOf("] ") > 0 ? c1.substring(0, c1.indexOf("] ") + "] ".length()).trim() : c1.trim();
                List<String> authList = authsToList(auths);
                if (units.contains("; ")) {
                    String[] unitList = units.split("; ");
                    for (String unit : unitList) {
                        C1Auth c1Auth = new C1Auth();
                        c1Auth.setAuthList(authList);
                        String info = dellEnd(unit);
                        c1Auth.setInfo(info);
                        // 为什么加1？这里是作者的序号，计算机中是从0开始，普通用户一般认为是从1开始，所以统一加1。
                        c1Auth.setSort(i + 1);
                        list.add(c1Auth);
                    }
                } else {
                    C1Auth c1Auth = new C1Auth();
                    c1Auth.setAuthList(authList);
                    String info = dellEnd(units);
                    c1Auth.setInfo(info);
                    c1Auth.setSort(i + 1);
                    list.add(c1Auth);
                }
            }
        }
        return list;
    }

    public static String dellEnd(String s) {
        s = s.trim();
        s = s.startsWith(",") ? s.substring(1).trim() : s;
        return s.endsWith(".") ? s.substring(0, s.length() - 1).trim() : s;
    }

    public static List<String> authsToList(String auths) {
        // 将作者的字符串，转换为list，如果作者只有空格而没有逗号，则添加上逗号，2025.01.14版本。
        auths = auths.endsWith("]") ? auths.substring(0, auths.length() - "]".length()).trim() : auths.trim();
        auths = auths.startsWith("[") ? auths.substring("[".length()).trim() : auths.trim();
        auths = auths.endsWith(".") ? auths.substring(0, auths.length() - ".".length()).trim() : auths.trim();
        String[] split = auths.split("; ");
        List<String> list = new ArrayList<>();
        for (String auth : split) {
            auth = dellEnd(auth);
            if (auth.length() > 3) {
                if (auth.contains(" ") && !auth.contains(",")) {
                    int i = auth.indexOf(" ");
                    String r = auth.substring(0, i) + ", " + auth.substring(i);
                    list.add(r.replaceAll(" +", " ").trim());
                } else {
                    list.add(auth.trim());
                }
            }
        }
        return list;
    }

    public static List<C1Auth> getRpList(String rps) {
        // 获取RP作者信息，2025.01.14版本
        List<C1Auth> list = new ArrayList<>();
        if (null != rps && rps.length() > 5) {
            String[] split = rps.replace(" (通讯作者)，", "ĺļ").replace("(reprint author),", "ĺļ").replace(" (corresponding author), ", "ĺļ").replaceAll(" +", " ").split("\\.; ");
            for (int i = 0; i < split.length; i++) {
                String[] split1 = split[i].split("ĺļ");
                if (split1.length == 2) {
                    C1Auth c1Auth = new C1Auth();
                    c1Auth.setAuthList(authsToList(split1[0]));
                    String info = dellEnd(split1[1]);
                    c1Auth.setInfo(info);
                    c1Auth.setSort(i + 1);
                    list.add(c1Auth);
                }
            }
        }
        return list;
    }

    @Data
    public static class C1Auth implements Serializable {
        private static final long serialVersionUID = 1L;
        private List<String> authList = new ArrayList<>(); // 原始的作者的集合
        private String info = ""; // 原始的单位信息
        private int sort = 0; // 作者的排序，第一作者为1，不是计算机中的0。
    }

    public static String checkGrammar(String kw) {
        // 检查检索语法，如果语法错误，返回错误信息，如果语法正确，返回原来的检索策略，如果原来的检索策略是引号的先给转成了括号。2025.03.03
        kw = yinHaoToKuoHao(kw);
        String result = kw;
        if (kw.contains("AD=(")) {
            kw = kw.replaceAll(" SAME \\(([^)]+)\\)", " SAME [$1]");
            while (true) {
                kw = kw.replaceAll("AD=\\(\\(([^)]+)\\)([^)]+)\\)", "AD=[[$1]$2]");
                Matcher matcher = Pattern.compile("\\(([^)]+)\\)").matcher(kw);
                if (matcher.find()) {
                    String group = matcher.group(1);
                    kw = kw.replace("(" + group + ")", "[" + group + "]");
                } else {
                    break;
                }
            }
        }
        if (kw.contains("(") || kw.contains(")") || kw.contains("\"") || !kw.contains("AD=[") || kw.contains(" SAME ]") || kw.contains(" AND ]") || kw.contains(" NOT ]") || kw.contains(" OR ]")
                || kw.contains(" SAME]") || kw.contains(" AND]") || kw.contains(" NOT]") || kw.contains(" OR]")) {
            return "检索语法错误！出现不成对的括号或引号或其它语法错误。";
        }
        return result;
    }

    public static String yinHaoToKuoHao(String kw) {
        // 将AD检索中的英文引号，转换成英文括号。AD="Beijing Hosp," -> AD=(Beijing Hosp,)  2025.03.03
        kw = kw.replace("“", "\"").replace("”", "\"").replace("（", "(").replace("）", ")").replaceAll(" +", " ")
                .replaceAll("(?i)AD=\"", "AD=\"").replaceAll("(?i)AD=\\(", "AD=(").replaceAll("(?i) SAME \"", " SAME \"").replaceAll("(?i) SAME \\(", " SAME (").trim();
        if (kw.contains("AD=\"")) {
            kw = kw.replaceAll(" SAME \"([^\"]+)\"", " SAME ($1)");
            while (true) {
                kw = kw.replaceAll("AD=\"\"([^\"]+)\"([^\"]+)\"", "AD=(($1)$2)");
                Matcher matcher = Pattern.compile("\"([^\"]+)\"").matcher(kw);
                if (matcher.find()) {
                    String group = matcher.group(1);
                    kw = kw.replace("\"" + group + "\"", "(" + group + ")");
                } else {
                    break;
                }
            }
        }
        return kw;
    }

    // 检查逻辑检索式，是否符合C1，即是否是第一或通讯作者，如果是返回true，如果不是返回false。不支持引号检索，比如：AD="Beijing Hosp,"
    public static boolean doCheck(String c1, String kw) {
        if (null == kw || kw.length() < 5 || null == c1 || c1.length() < 5 || kw.contains("检索语法错误！出现不成对的括号或引号或其它语法错误。")) {
            return false;
        }
        kw = sameChange(kw);
        c1 = c1.toUpperCase();
        kw = reStr(kw);
        if (!kw.contains(" NOT ") && !kw.contains(" AND ") && !kw.contains(" OR ")) {
            String result = (kw.startsWith("AD=À") && kw.endsWith("Á")) ? kw.substring("AD=À".length(), kw.length() - "Á".length()) : kw;
            if (c1.contains(result) || wildcardsFalse(c1, result)) {
                return true;
            }
        }

        for (int i = 0; i < kw.length(); i++) {
            if (kw.contains("AD=À") && kw.contains("Á")) {
                Matcher matcher = Pattern.compile("AD=À([^ÀÁ]+)Á").matcher(kw);
                while (matcher.find()) {
                    String search = matcher.group(1);
                    String logic = (c1.contains(search) || wildcardsFalse(c1, search)) ? "⬇TRUE" : "⬇FALSE";
                    kw = kw.replace("AD=À" + search + "Á", logic).replaceAll(" +", " ");
                }
            } else {
                break;
            }
        }
        kw = kw.replace("À", "(").replace("Á", ")").replace("⬇FALSE", "false").replace("⬇TRUE", "true").replace(" NOT ", " AND !");
        return evaluateExpression(kw);
    }

    public static boolean evaluateExpression(String expr) {
        // 将字符串格式的逻辑运算式，转换为运算后的布尔值，比如字符串：true OR false AND false AND !false。此方法需要加依赖：<groupId>org.springframework</groupId>
        ExpressionParser parser = new SpelExpressionParser();
        Expression expression = parser.parseExpression(expr);
        try {
            return Boolean.TRUE.equals(expression.getValue(Boolean.class));
        } catch (EvaluationException e) {
//            throw new RuntimeException(e);
        }
        return false;
    }

    // 增加对相邻检索SAME的支持
    public static String sameChange(String str) {
        String t = str.replaceAll(" +", " ").replace("（", "À").replace("）", "Á").replace(" =", "=").replace("= ", "=")
                .replace("(", "À").replace(")", "Á").replace("Á Á", "ÁÁ").replace("À À", "ÀÀ");
        String[] split = t.toUpperCase().replace("\"", "").trim().split("");
        int size = split.length;
        StringBuilder result = new StringBuilder();
        for (int i = 0; i < size; i++) {
            if ("A".equals(split[i]) && size > (i + 3)) {
                if ("AD=À".equals(split[i] + split[i + 1] + split[i + 2] + split[i + 3])) {
                    StringBuilder ad = new StringBuilder();
                    int sum = 0;
                    for (int j = i; j < size; j++) {
                        ad.append(split[j]);
                        if ("À".equals(split[j])) {
                            sum++;
                        }
                        if ("Á".equals(split[j])) {
                            sum--;
                            if (sum == 0) {
                                break;
                            }
                        }
                    }
                    String replace = "";
                    if (ad.toString().contains(" SAME ")) { // AD=ÀQILU HOSP* SAME AD=ÀJINANÁ OR AD=ÀQINGDAOÁÁ    AD=ÀQI LU HOSP* SAME AD=ÀJINANÁ OR AD=ÀQINGDAOÁ SAME ABCÁ   // AD=ÀÀSHANGHAIÁ SAME ÀJIAO TONG UNIVÁ SAME ÀSCH MEDÁÁ
                        String[] list = ad.toString().replaceAll("À+", "À").replaceAll("Á+", "Á").split(" SAME ");
                        StringBuilder r = new StringBuilder();
                        for (String s : list) {
                            if (s.trim().length() > 1) {
                                if (s.startsWith("AD=À")) {
                                    if (s.endsWith("Á")) {
                                        r.append("À").append(Or(s.substring("AD=À".length(), s.length() - "Á".length()))).append("Á AND ");
                                    } else {
                                        r.append("À").append(Or(s.substring("AD=À".length()))).append("Á AND ");
                                    }
                                } else if (s.startsWith("À")) {
                                    if (s.endsWith("Á")) {
                                        r.append("À").append(Or(s.substring("À".length(), s.length() - "Á".length()))).append("Á AND ");
                                    } else {
                                        r.append("À").append(Or(s.substring("À".length()))).append("Á AND ");
                                    }
                                } else {
                                    if (s.endsWith("Á")) {
                                        r.append("À").append(Or(s.substring(0, s.length() - "Á".length()))).append("Á AND ");
                                    } else {
                                        r.append("À").append(Or(s)).append("Á AND ");
                                    }
                                }
                            }
                        }
                        if (r.length() > 5 && r.toString().endsWith(" AND ")) {
                            r = new StringBuilder(r.substring(0, r.length() - " AND ".length()));
                        }
                        replace = "À" + r + "Á";
                    } else {
                        replace = ad.toString();
                    }
                    result.append(replace);
                    i += ad.length() - 1;
                } else {
                    result.append(split[i]);
                }
            } else {
                result.append(split[i]);
            }
        }
        return addBracket(result.toString());
    }

    // 括号内的OR运算
    public static String Or(String str) {
        String[] split = str.replace("À", "").replace("Á", "").split(" OR ");
        StringBuilder r = new StringBuilder();
        for (String s : split) {
            r.append(" OR AD=À").append(s).append("Á");
        }
        if (r.length() > 4) {
            r = new StringBuilder(r.substring(4));
        }
        return r.toString();
    }

    // 统一规范检索式，要求所有的检索词均被括号括起来，如果没有括号的，给加上。加上后，再把检索式的括号给改成引号引起来，这里的引号使用特殊的字符串：À->左引号或左括号  Á->右引号或右括号
    public static String addBracket(String str) {
        str = str.toUpperCase().replaceAll(" +", " ").replace(" )", ")").replace("( ", "(").replace(" =", "=").replace("= ", "=").replace(")", "Á").replace("(", "À").trim();
        String[] split = str.split("");
        StringBuilder result = new StringBuilder();
        boolean bool = false;
        for (int i = 0; i < split.length; i++) {
            String t = split[i];
            if ("=".equals(t) && split.length > i + 1 && i > 1 && !"À".equals(split[i + 1]) && "D".equals(split[i - 1]) && "A".equals(split[i - 2])) {
                result.append(t);
                result.append("À");
                bool = true;
                continue;
            }
            if (bool) {
                if (" ".equals(t) || "Á".equals(t)) {
                    result.append("Á");
                    bool = false;
                }
            }
            result.append(t);
        }
        if (bool) {
            result.append("Á");
        }
        return result.toString();
    }

    // .*?表示：0或N个  .+?表示：1或N个，这里采用0或N个  例：String c1 = "Liao cheng Peoples Hosp, Liaocheng 252002, Shandong, Peoples R China.";   String str = "AD=(Liao*Cheng People* Hosp)";
    public static boolean wildcardsFalse(String c1, String result) {
        if (result.contains("*")) {
            String w = result.replace("*", ".*?"); // Liao*Cheng People* Hosp -> LIAO.*?CHENG PEOPLE.*? HOSP
            Matcher matcher = Pattern.compile(w).matcher(c1);  // c1:LIAO CHENG PEOPLES HOSP, LIAOCHENG 252002, SHANDONG, PEOPLES R CHINA.
            return matcher.find();
        } else if (result.contains("?")) {
            String w = result.replace("?", ".?"); // 0到1个
            Matcher matcher = Pattern.compile(w).matcher(c1);  //
            return matcher.find();
        }
        return false;
    }

    public static String reStr(String str) {
        return str.replaceAll(" +", " ").replace("À ", "À").replace(" Á", "Á").replace(" )", ")").replace("( ", "(").replace(" =", "=")
                .replace("= ", "=").replace("AD=⬇FALSE", "⬇FALSE").replace("AD=⬇TRUE", "⬇TRUE").trim();
    }


    public static Set<String> getEarly2024() {
        Set<String> set = new HashSet<>();
        set.add("ENVIRON SCI POLLUT R");
        set.add("EXP THER MED");
        set.add("J CLIN MED");
        set.add("FRONTIERS IN ENERGY RESEARCH");
        set.add("JOURNAL OF PERSONALIZED MEDICINE");
        set.add("J BIOMATER TISSUE ENG");
        set.add("JOURNAL OF NANOELECTRONICS AND OPTOELECTRONICS");
        set.add("MULTIMED TOOLS APPL");
        set.add("PSYCHIATRIA DANUBINA");
        set.add("FUEL");
        set.add("SCIENCE OF ADVANCED MATERIALS");
        set.add("J SENS");
        set.add("MATH BIOSCI ENG");
        set.add("RADIOLOGIA MEDICA");
        set.add("EXPERIMENTAL AND THERAPEUTIC MEDICINE");
        set.add("MATER EXPRESS");
        set.add("CONNECT SCI");
        set.add("MULTIMEDIA TOOLS AND APPLICATIONS");
        set.add("RADIOL MED");
        set.add("DIAGNOSTICS");
        set.add("MATERIALS EXPRESS");
        set.add("J SENSORS");
        set.add("JOURNAL OF BIOMEDICAL NANOTECHNOLOGY");
        set.add("CONNECTION SCIENCE");
        set.add("CANCERS");
        set.add("FRONT ENERGY RES");
        set.add("ALTERNATIVE THERAPIES IN HEALTH AND MEDICINE");
        set.add("J BIOMATER TISS ENG");
        set.add("JOURNAL OF BIOMATERIALS AND TISSUE ENGINEERING");
        set.add("J NANOELECTRON OPTOELECTRON");
        set.add("PSYCHIATR DANUB");
        set.add("J NANOELECTRON OPTOE");
        set.add("CMES COMP MODEL ENG");
        set.add("ALTERN THER HEALTH M");
        set.add("CMES COMPUTER MODELING IN ENGINEERING & SCIENCES");
        set.add("J BIOBASED MATER BIOENERGY");
        set.add("JOURNAL OF CLINICAL MEDICINE");
        set.add("TROPICAL JOURNAL OF PHARMACEUTICAL RESEARCH");
        set.add("J PERS MED");
        set.add("PSYCHIAT DANUB");
        set.add("ENVIRONMENTAL SCIENCE AND POLLUTION RESEARCH");
        set.add("TROP J PHARM RES");
        set.add("ENVIRON SCI POLLUT RES");
        set.add("SCI ADV MATER");
        set.add("J BIOMED NANOTECHNOL");
        set.add("MATHEMATICAL BIOSCIENCES AND ENGINEERING");
        set.add("JOURNAL OF SENSORS");
        set.add("J BIOBASED MATER BIO");
        set.add("JOURNAL OF BIOBASED MATERIALS AND BIOENERGY");
        set.add("ALTERN THER HEALTH MED");
        set.add("CMES COMP MODEL ENG SCI");
        set.add("BIOENGINEERED");
        set.add("101526829");
        set.add("101658402");
        set.add("9441769");
        set.add("101556828");
        set.add("101606588");
        set.add("101602269");
        set.add("0177625");
        set.add("101581063");
        set.add("9012163");
        set.add("101555932");
        set.add("9424753");
        set.add("101291525");
        set.add("101591609");
        set.add("101230869");
        set.add("101703746");
        set.add("101598992");
        set.add("9502013");
        set.add("101511516");
        set.add("101531947");
        set.add("101638683");
        set.add("101197794");
        set.add("101214391");
        set.add("CMES-COMPUTER MODELING IN ENGINEERING & SCIENCES");
        set.add("0944-1344");
        set.add("0016-2361");
        set.add("0033-8362");
        set.add("2165-5979");
        set.add("0954-0091");
        set.add("1380-7501");
        set.add("0353-5053");
        set.add("1556-6560");
        set.add("2157-9083");
        set.add("1550-7033");
        set.add("1555-130X");
        set.add("1687-725X");
        set.add("2158-5849");
        set.add("1947-2935");
        set.add("1078-6791");
        set.add("1526-1492");
        set.add("1792-0981");
        set.add("2296-598X");
        set.add("1547-1063");
        set.add("1596-5996");
        set.add("2072-6694");
        set.add("2075-4418");
        set.add("1614-7499");
        set.add("1873-7153");
        set.add("2077-0383");
        set.add("2075-4426");
        set.add("1826-6983");
        set.add("2165-5987");
        set.add("1360-0494");
        set.add("1573-7721");
        set.add("1849-0867");
        set.add("1556-6579");
        set.add("2157-9091");
        set.add("1550-7041");
        set.add("1555-1318");
        set.add("1687-7268");
        set.add("2158-5857");
        set.add("1947-2943");
        set.add("1526-1506");
        set.add("1792-1015");
        set.add("1551-0018");
        set.add("CMES-COMP MODEL ENG");
        set.add("ENVIRON. SCI. POLLUT. RES.");
        set.add("J. CLIN. MED.");
        set.add("J. PERS. MED.");
        set.add("RADIOL. MED.");
        set.add("CONNECT. SCI.");
        set.add("MULTIMED. TOOLS APPL.");
        set.add("PSYCHIATR. DANUB.");
        set.add("J. BIOBASED MATER. BIOENERGY");
        set.add("J. BIOMATER. TISSUE ENG.");
        set.add("J. BIOMED. NANOTECHNOL.");
        set.add("J. NANOELECTRON. OPTOELECTRON.");
        set.add("J. SENS.");
        set.add("MATER. EXPRESS");
        set.add("SCI. ADV. MATER.");
        set.add("ALTERN. THER. HEALTH MED.");
        set.add("CMES-COMP. MODEL. ENG. SCI.");
        set.add("EXP. THER. MED.");
        set.add("FRONT. ENERGY RES.");
        set.add("MATH. BIOSCI. ENG.");
        set.add("TROP. J. PHARM. RES.");
        return set;
    }

    public static Set<String> getEarly2023() {
        Set<String> set = new HashSet<>();
        set.add("JOURNAL OF ENVIRONMENTAL AND PUBLIC HEALTH");
        set.add("9424753");
        set.add("J CLIN LAB ANAL");
        set.add("WORLD JOURNAL OF CLINICAL CASES");
        set.add("101682385");
        set.add("101591609");
        set.add("JOURNAL OF CLINICAL LABORATORY ANALYSIS");
        set.add("TEXTILE RESEARCH JOURNAL");
        set.add("BUILDINGS BASEL");
        set.add("INT J CONTROL AUTOM");
        set.add("MACHINES");
        set.add("J BIOMATER TISSUE ENG");
        set.add("101512861");
        set.add("PSYCHIATRIA DANUBINA");
        set.add("ACTA MEDICA MEDITERRANEA");
        set.add("J STRUCT CHEM");
        set.add("ECON RES EKON ISTRAZ");
        set.add("FRONT ENVIRON SCI");
        set.add("FRONT EARTH SCI");
        set.add("FRONTIERS IN EARTH SCIENCE");
        set.add("9878794");
        set.add("MICROPROCESS MICROSYST");
        set.add("INT J CONTROL AUTOM SYST");
        set.add("EKON ISTRAZ");
        set.add("ENERGY REPORTS");
        set.add("INTERNATIONAL JOURNAL OF ELECTROCHEMICAL SCIENCE");
        set.add("FRONT SURG");
        set.add("101493030");
        set.add("PHARMAZIE");
        set.add("MATH PROBL ENG");
        set.add("INT J ELECTROCHEM SCI");
        set.add("WORLD J CLIN CASES");
        set.add("COMPUTATIONAL AND MATHEMATICAL METHODS IN MEDICINE");
        set.add("AMERICAN JOURNAL OF TRANSLATIONAL RESEARCH");
        set.add("101735833");
        set.add("JOURNAL OF INDUSTRIAL AND MANAGEMENT OPTIMIZATION");
        set.add("INORGANIC AND NANO METAL CHEMISTRY");
        set.add("AEROSPACE BASEL");
        set.add("INTERNATIONAL JOURNAL OF CONTROL AUTOMATION AND SYSTEMS");
        set.add("MOB INF SYST");
        set.add("BUILDINGS");
        set.add("COMPUT MATH METHOD M");
        set.add("101721978");
        set.add("FOOD SCIENCE AND TECHNOLOGY");
        set.add("FOOD SCI TECHNOL");
        set.add("FRONT EARTH SC SWITZ");
        set.add("MATHEMATICAL PROBLEMS IN ENGINEERING");
        set.add("J BIOMATER TISS ENG");
        set.add("JOURNAL OF BIOMATERIALS AND TISSUE ENGINEERING");
        set.add("TEXT RES J");
        set.add("MICROPROCESS MICROSY");
        set.add("ECONOMIC RESEARCH EKONOMSKA ISTRAZIVANJA");
        set.add("PSYCHIATR DANUB");
        set.add("FRONT ENV SCI SWITZ");
        set.add("J STRUCT CHEM+");
        set.add("MOBILE INFORMATION SYSTEMS");
        set.add("ENERGY REP");
        set.add("GEOFLUIDS");
        set.add("FOOD SCI TECH BRAZIL");
        set.add("101516361");
        set.add("AM J TRANSL RES");
        set.add("MICROPROCESSORS AND MICROSYSTEMS");
        set.add("PSYCHIAT DANUB");
        set.add("101748773");
        set.add("INORG NANO MET CHEM");
        set.add("J ENVIRON PUBLIC HEA");
        set.add("INT J ELECTROCHEM SC");
        set.add("101277751");
        set.add("101618806");
        set.add("J IND MANAG OPTIM");
        set.add("8801384");
        set.add("FRONTIERS IN SURGERY");
        set.add("JOURNAL OF STRUCTURAL CHEMISTRY");
        set.add("100954992");
        set.add("101645127");
        set.add("ACTA MEDICA MEDITERR");
        set.add("J ENVIRON PUBLIC HEALTH");
        set.add("AEROSPACE");
        set.add("FRONTIERS IN ENVIRONMENTAL SCIENCE");
        set.add("9800766");
        set.add("COMPUT MATH METHOD MED");
        set.add("101638676");
        set.add("INORGANIC AND NANO-METAL CHEMISTRY");
        set.add("ECONOMIC RESEARCH-EKONOMSKA ISTRAZIVANJA");
        set.add("0040-5175");
        set.add("1468-8115");
        set.add("1547-5816");
        set.add("1024-123X");
        set.add("1748-670X");
        set.add("2352-4847");
        set.add("2470-1556");
        set.add("0022-4766");
        set.add("1452-3981");
        set.add("0141-9331");
        set.add("1598-6446");
        set.add("1574-017X");
        set.add("1331-677X");
        set.add("0101-2061");
        set.add("1687-9805");
        set.add("0031-7144");
        set.add("0353-5053");
        set.add("0393-6384");
        set.add("1943-8141");
        set.add("2157-9083");
        set.add("0887-8013");
        set.add("2307-8960");
        set.add("2296-875X");
        set.add("1746-7748");
        set.add("1468-8123");
        set.add("2296-6463");
        set.add("1553-166X");
        set.add("1563-5147");
        set.add("2226-4310");
        set.add("2075-5309");
        set.add("1748-6718");
        set.add("2075-1702");
        set.add("2470-1564");
        set.add("1573-8779");
        set.add("2296-665X");
        set.add("1872-9436");
        set.add("2005-4092");
        set.add("1875-905X");
        set.add("1848-9664");
        set.add("1678-457X");
        set.add("1687-9813");
        set.add("1849-0867");
        set.add("2283-9720");
        set.add("2157-9091");
        set.add("1098-2825");
        set.add("FRONT EARTH SC-SWITZ");
        set.add("AEROSPACE-BASEL");
        set.add("BUILDINGS-BASEL");
        set.add("INORG NANO-MET CHEM");
        set.add("FRONT ENV SCI-SWITZ");
        set.add("ECON RES-EKON ISTRAZ");
        set.add("FOOD SCI TECH-BRAZIL");
        set.add("TEXT. RES. J.");
        set.add("FRONT. EARTH SCI.");
        set.add("J. IND. MANAG. OPTIM.");
        set.add("MATH. PROBL. ENG.");
        set.add("COMPUT. MATH. METHOD MED.");
        set.add("ENERGY REP.");
        set.add("INORG. NANO-MET. CHEM.");
        set.add("J. STRUCT. CHEM.");
        set.add("INT. J. ELECTROCHEM. SCI.");
        set.add("FRONT. ENVIRON. SCI.");
        set.add("MICROPROCESS. MICROSYST.");
        set.add("INT. J. CONTROL AUTOM. SYST.");
        set.add("MOB. INF. SYST.");
        set.add("EKON. ISTRAZ.");
        set.add("FOOD SCI. TECHNOL.");
        set.add("J. ENVIRON. PUBLIC HEALTH");
        set.add("PSYCHIATR. DANUB.");
        set.add("ACTA MEDICA MEDITERR.");
        set.add("AM. J. TRANSL. RES.");
        set.add("J. BIOMATER. TISSUE ENG.");
        set.add("J. CLIN. LAB. ANAL.");
        set.add("WORLD J. CLIN. CASES");
        set.add("FRONT. SURG.");
        return set;
    }

    public static Set<String> getEarly2021() {
        Set<String> set = new HashSet<>();
        set.add("AIMS MATHEMATICS");
        set.add("FRONT CELL DEV BIOL");
        set.add("101629355");
        set.add("SCI PROGRAMMING NETH");
        set.add("MOL THER NUCL ACIDS");
        set.add("VACCINES");
        set.add("101658402");
        set.add("MICROPROCESS MICROSYST");
        set.add("AGING US");
        set.add("PHARMAZIE");
        set.add("JOURNAL OF CELLULAR AND MOLECULAR MEDICINE");
        set.add("101778895");
        set.add("WORLD J CLIN CASES");
        set.add("J MATH");
        set.add("9891351");
        set.add("ANNALS OF PALLIATIVE MEDICINE");
        set.add("9888589");
        set.add("101586313");
        set.add("101676334");
        set.add("INT J GEN MED");
        set.add("SHOCK AND VIBRATION");
        set.add("AIMS MATH");
        set.add("SHOCK VIB");
        set.add("0346411");
        set.add("101475259");
        set.add("MITOCHONDRIAL DNA PART B RESOURCES");
        set.add("FRONTIERS IN CELL AND DEVELOPMENTAL BIOLOGY");
        set.add("101535920");
        set.add("JOURNAL OF MATHEMATICS");
        set.add("ONCOTARGETS THER");
        set.add("EXPERIMENTAL AND MOLECULAR PATHOLOGY");
        set.add("COMPLEXITY");
        set.add("FRONT MED LAUSANNE");
        set.add("BIOFACTORS");
        set.add("J PERS MED");
        set.add("SCI PROGRAM");
        set.add("9609063");
        set.add("HEALTHCARE");
        set.add("JOURNAL OF INTERNATIONAL MEDICAL RESEARCH");
        set.add("FRONTIERS IN MEDICINE");
        set.add("MOL MED REP");
        set.add("ANN PALLIAT MED");
        set.add("101602269");
        set.add("101585484");
        set.add("101515487");
        set.add("HEALTHCARE BASEL");
        set.add("FRONT MOL BIOSCI");
        set.add("CANCER CELL INT");
        set.add("J MATH UK");
        set.add("CANCER MANAG RES");
        set.add("JOURNAL OF CANCER");
        set.add("WORLD JOURNAL OF CLINICAL CASES");
        set.add("ANN PALLLIAT MED");
        set.add("101512700");
        set.add("MITOCHONDRIAL DNA PART B RESOUR");
        set.add("JOURNAL OF PERSONALIZED MEDICINE");
        set.add("101514322");
        set.add("ADV CIV ENG");
        set.add("INTERNATIONAL JOURNAL OF GENERAL MEDICINE");
        set.add("101691304");
        set.add("BIOLOGY BASEL");
        set.add("9878794");
        set.add("101630250");
        set.add("101508617");
        set.add("CANCER CELL INTERNATIONAL");
        set.add("ONCOTARGETS AND THERAPY");
        set.add("101139795");
        set.add("VACCINES BASEL");
        set.add("0370711");
        set.add("101581621");
        set.add("FRONT MED");
        set.add("EXP MOL PATHOL");
        set.add("DIAGNOSTICS");
        set.add("MOLECULAR THERAPY NUCLEIC ACIDS");
        set.add("CANCER MANAGEMENT AND RESEARCH");
        set.add("101083777");
        set.add("MICROPROCESS MICROSY");
        set.add("MED SCI MONITOR");
        set.add("SCIENTIFIC PROGRAMMING");
        set.add("101648047");
        set.add("MICROPROCESSORS AND MICROSYSTEMS");
        set.add("DISCRETE DYN NAT SOC");
        set.add("MEDICAL SCIENCE MONITOR");
        set.add("ADVANCES IN CIVIL ENGINEERING");
        set.add("8807441");
        set.add("101653173");
        set.add("MOLECULAR MEDICINE REPORTS");
        set.add("101580444");
        set.add("101618806");
        set.add("MITOCHONDRIAL DNA B");
        set.add("FRONTIERS IN MOLECULAR BIOSCIENCES");
        set.add("101666525");
        set.add("BIOMEDICINES");
        set.add("101587988");
        set.add("DISCRETE DYNAMICS IN NATURE AND SOCIETY");
        set.add("9800766");
        set.add("LIFE BASEL");
        set.add("J INT MED RES");
        set.add("J CANCER");
        set.add("J CELL MOL MED");
        set.add("MITOCHONDRIAL DNA PART B-RESOURCES");
        set.add("LIFE-BASEL");
        set.add("BIOLOGY-BASEL");
        set.add("MOLECULAR THERAPY-NUCLEIC ACIDS");
        set.add("AGING-US");
        set.add("1076-2787");
        set.add("1070-9622");
        set.add("1687-8086");
        set.add("0141-9331");
        set.add("1058-9244");
        set.add("0951-6433");
        set.add("2296-634X");
        set.add("1026-0226");
        set.add("2314-4629");
        set.add("0031-7144");
        set.add("2162-2531");
        set.add("0014-4800");
        set.add("1582-1838");
        set.add("1791-2997");
        set.add("0300-0605");
        set.add("1837-9664");
        set.add("1945-4589");
        set.add("1178-6930");
        set.add("1179-1322");
        set.add("2307-8960");
        set.add("2224-5820");
        set.add("1099-0526");
        set.add("1875-9203");
        set.add("1687-8094");
        set.add("2227-9059");
        set.add("1872-9436");
        set.add("1875-919X");
        set.add("1872-8081");
        set.add("2380-2359");
        set.add("2296-889X");
        set.add("2075-1729");
        set.add("2079-7737");
        set.add("1607-887X");
        set.add("2473-6988");
        set.add("2314-4785");
        set.add("1096-0945");
        set.add("1582-4934");
        set.add("1791-3004");
        set.add("1473-2300");
        set.add("1643-3750");
        set.add("1475-2867");
        set.add("2224-5839");
        set.add("1178-7074");
        set.add("2296-858X");
        set.add("2075-4426");
        set.add("2227-9032");
        set.add("2075-4418");
        set.add("2076-393X");
        set.add("SCI PROGRAMMING-NETH");
        set.add("J MATH-UK");
        set.add("MOL THER-NUCL ACIDS");
        set.add("FRONT MED-LAUSANNE");
        set.add("HEALTHCARE-BASEL");
        set.add("VACCINES-BASEL");
        set.add("SHOCK VIB.");
        set.add("ADV. CIV. ENG.");
        set.add("MICROPROCESS. MICROSYST.");
        set.add("SCI. PROGRAM.");
        set.add("MITOCHONDRIAL DNA PART B-RESOUR.");
        set.add("FRONT. MOL. BIOSCI.");
        set.add("FRONT. CELL. DEV. BIOL.");
        set.add("DISCRETE DYN. NAT. SOC.");
        set.add("AIMS MATH.");
        set.add("J. MATH.");
        set.add("MOL. THER.-NUCL. ACIDS");
        set.add("EXP. MOL. PATHOL.");
        set.add("J. CELL. MOL. MED.");
        set.add("MOL. MED. REP.");
        set.add("J. INT. MED. RES.");
        set.add("J. CANCER");
        set.add("MED. SCI. MONITOR");
        set.add("ONCOTARGETS THER.");
        set.add("CANCER MANAG. RES.");
        set.add("CANCER CELL INT.");
        set.add("WORLD J. CLIN. CASES");
        set.add("ANN. PALLLIAT. MED.");
        set.add("INT. J. GEN. MED.");
        set.add("FRONT. MED.");
        set.add("J. PERS. MED.");
        return set;
    }

    public static Set<String> getEarly2020() {
        Set<String> set = new HashSet<>();
        set.add("101531947");
        set.add("9717360");
        set.add("EXP THER MED");
        set.add("INT J ENERG RES");
        set.add("ONCOL RES");
        set.add("J CLIN MED");
        set.add("BIOSCI REP");
        set.add("101776982");
        set.add("ARTIF CELL NANOMED B");
        set.add("INTERNATIONAL JOURNAL OF ENVIRONMENTAL RESEARCH AND PUBLIC HEALTH");
        set.add("101599172");
        set.add("CATALYSTS");
        set.add("WATER");
        set.add("0375521");
        set.add("101580302");
        set.add("101555929");
        set.add("ATMOSPHERE");
        set.add("101670234");
        set.add("AMERICAN JOURNAL OF TRANSLATIONAL RESEARCH");
        set.add("101088195");
        set.add("101695672");
        set.add("8205768");
        set.add("ONCOLOGY REPORTS");
        set.add("MATHEMATICAL PROBLEMS IN ENGINEERING");
        set.add("J CELL BIOCHEM");
        set.add("0346411");
        set.add("J BIOMATER TISS ENG");
        set.add("101475259");
        set.add("ONCOLOGY RESEARCH");
        set.add("9422756");
        set.add("8102797");
        set.add("ZEITSCHRIFT FUR KRISTALLOGRAPHIE NEW CRYSTAL STRUCTURES");
        set.add("MINERALS BASEL");
        set.add("INTERNATIONAL JOURNAL OF CLINICAL AND EXPERIMENTAL PATHOLOGY");
        set.add("BRAZILIAN JOURNAL OF MEDICAL AND BIOLOGICAL RESEARCH");
        set.add("COATINGS");
        set.add("BIOFACTORS");
        set.add("101204366");
        set.add("JOURNAL OF INTERNATIONAL MEDICAL RESEARCH");
        set.add("MOL MED REP");
        set.add("101546871");
        set.add("Z KRIST NEW CRYST ST");
        set.add("INTERNATIONAL JOURNAL OF ENERGY RESEARCH");
        set.add("101606588");
        set.add("ACTA MEDICA MEDITERR");
        set.add("INT J ENV RES PUB HE");
        set.add("EUR REV MED PHARMACOL SCI");
        set.add("INT J CLIN EXP PATHO");
        set.add("APPL SCI BASEL");
        set.add("ADV DIFFER EQU NY");
        set.add("CANCER BIOMARK");
        set.add("101664675");
        set.add("101600173");
        set.add("101739125");
        set.add("101514322");
        set.add("ADV CIV ENG");
        set.add("ACTA MEDICA MEDITERRANEA");
        set.add("ELECTRONICS");
        set.add("ADVANCES IN DIFFERENCE EQUATIONS");
        set.add("AMERICAN JOURNAL OF CANCER RESEARCH");
        set.add("POLYMERS BASEL");
        set.add("BRAZ J MED BIOL RES");
        set.add("SUSTAINABILITY BASEL");
        set.add("ONCOTARGETS AND THERAPY");
        set.add("101167924");
        set.add("EXPERIMENTAL AND THERAPEUTIC MEDICINE");
        set.add("101493030");
        set.add("J NANOSCI NANOTECHNO");
        set.add("INT J ELECTROCHEM SCI");
        set.add("101671521");
        set.add("BIOMED RES INT");
        set.add("101594777");
        set.add("MATERIALS");
        set.add("101721978");
        set.add("JOURNAL OF NANOSCIENCE AND NANOTECHNOLOGY");
        set.add("JOURNAL OF CELLULAR BIOCHEMISTRY");
        set.add("JOURNAL OF BIOMATERIALS AND TISSUE ENGINEERING");
        set.add("MATHEMATICS BASEL");
        set.add("8213295");
        set.add("MEDICINE");
        set.add("101471010");
        set.add("AM J TRANSL RES");
        set.add("BIOSCIENCE REPORTS");
        set.add("MEDICAL SCIENCE MONITOR");
        set.add("ADVANCES IN CIVIL ENGINEERING");
        set.add("101653204");
        set.add("CELLS");
        set.add("101579976");
        set.add("JOURNAL OF CELLULAR PHYSIOLOGY");
        set.add("101531236");
        set.add("101697598");
        set.add("J INT MED RES");
        set.add("101748883");
        set.add("WATER SUI");
        set.add("INT J CLIN EXP PATHOL");
        set.add("LIFE SCIENCES");
        set.add("BIOMED RESEARCH INTERNATIONAL");
        set.add("EUROPEAN REVIEW FOR MEDICAL AND PHARMACOLOGICAL SCIENCES");
        set.add("101591609");
        set.add("SENSORS");
        set.add("PLANTS BASEL");
        set.add("ELECTRONICS SWITZ");
        set.add("METALS");
        set.add("ADV DIFFER EQU");
        set.add("101596181");
        set.add("LIFE SCI");
        set.add("ENERGIES");
        set.add("ATMOSPHERE BASEL");
        set.add("APPLIED SCIENCES BASEL");
        set.add("BOUNDARY VALUE PROBLEMS");
        set.add("DESALIN WATER TREAT");
        set.add("ARTIFICIAL CELLS NANOMEDICINE AND BIOTECHNOLOGY");
        set.add("INTERNATIONAL JOURNAL OF ELECTROCHEMICAL SCIENCE");
        set.add("AGING US");
        set.add("J CELL PHYSIOL");
        set.add("101480565");
        set.add("Z KRIST NEW CRYST STRUCT");
        set.add("9888589");
        set.add("DESALINATION AND WATER TREATMENT");
        set.add("8911335");
        set.add("BOUND VALUE PROBL");
        set.add("101630280");
        set.add("JOURNAL OF INEQUALITIES AND APPLICATIONS");
        set.add("ONCOL LETT");
        set.add("METALS BASEL");
        set.add("101238455");
        set.add("ONCOTARGETS THER");
        set.add("EXPERIMENTAL AND MOLECULAR PATHOLOGY");
        set.add("COMPLEXITY");
        set.add("ONCOLOGY LETTERS");
        set.add("9609063");
        set.add("0050222");
        set.add("EUR REV MED PHARMACO");
        set.add("101613952");
        set.add("INT J ELECTROCHEM SC");
        set.add("INTERNATIONAL JOURNAL OF MOLECULAR MEDICINE");
        set.add("AM J CANCER RES");
        set.add("INT J ENVIRON RES PUBLIC HEALTH");
        set.add("INT J MOL MED");
        set.add("POLYMERS");
        set.add("100964009");
        set.add("ARTIF CELL NANOMED BIOTECHNOL");
        set.add("101633495");
        set.add("101256509");
        set.add("101682385");
        set.add("101666579");
        set.add("101562250");
        set.add("BIOMED PHARMACOTHER");
        set.add("MOLECULES");
        set.add("J BIOMATER TISSUE ENG");
        set.add("INT J ENERGY RES");
        set.add("101545357");
        set.add("INTERNATIONAL JOURNAL OF CLINICAL AND EXPERIMENTAL MEDICINE");
        set.add("9208097");
        set.add("INT J CLIN EXP MED");
        set.add("101508617");
        set.add("MINERALS");
        set.add("SUSTAINABILITY");
        set.add("MATH PROBL ENG");
        set.add("2985248R");
        set.add("101639462");
        set.add("0370711");
        set.add("NATURAL PRODUCT RESEARCH");
        set.add("EXP MOL PATHOL");
        set.add("9810955");
        set.add("101766564");
        set.add("8112917");
        set.add("J NANOSCI NANOTECHNOL");
        set.add("MATHEMATICS");
        set.add("MEDICINE (BALTIMORE)");
        set.add("INTERNATIONAL JOURNAL OF IMMUNOPATHOLOGY AND PHARMACOLOGY");
        set.add("MED SCI MONITOR");
        set.add("JOURNAL OF CLINICAL MEDICINE");
        set.add("BRAZILIAN J MED BIOL RES");
        set.add("8807441");
        set.add("MOLECULAR MEDICINE REPORTS");
        set.add("CANCER BIOMARKERS");
        set.add("J INEQUAL APPL");
        set.add("NAT PROD RES");
        set.add("SYMMETRY BASEL");
        set.add("PROCESSES");
        set.add("INT J IMMUNOPATH PH");
        set.add("INT J IMMUNOPATHOL PHARMACOL");
        set.add("SENSORS BASEL");
        set.add("IEEE ACCESS");
        set.add("AGRONOMY BASEL");
        set.add("BIOMEDICINE & PHARMACOTHERAPY");
        set.add("ONCOL REP");
        set.add("101549944");
        set.add("101769288");
        set.add("BIOSCIENCE REP");
        set.add("CELLS BASEL");
        set.add("APPLIED SCIENCES-BASEL");
        set.add("ZEITSCHRIFT FUR KRISTALLOGRAPHIE-NEW CRYSTAL STRUCTURES");
        set.add("AGRONOMY-BASEL");
        set.add("PLANTS-BASEL");
        set.add("AGING-US");
        set.add("SYMMETRY-BASEL");
        set.add("1533-4880");
        set.add("2169-1401");
        set.add("1687-8086");
        set.add("0363-907X");
        set.add("1024-123X");
        set.add("1076-2787");
        set.add("1944-3994");
        set.add("1452-3981");
        set.add("1478-6419");
        set.add("1433-7266");
        set.add("2169-3536");
        set.add("0730-2312");
        set.add("0021-9541");
        set.add("0144-8463");
        set.add("2314-6133");
        set.add("0951-6433");
        set.add("1687-2770");
        set.add("1687-1847");
        set.add("1029-242X");
        set.add("1128-3602");
        set.add("1936-2625");
        set.add("0025-7974");
        set.add("1940-5901");
        set.add("0753-3322");
        set.add("0014-4800");
        set.add("0100-879X");
        set.add("1574-0153");
        set.add("0394-6320");
        set.add("0965-0407");
        set.add("2156-6976");
        set.add("1792-1074");
        set.add("1792-0981");
        set.add("1178-6930");
        set.add("1021-335X");
        set.add("1791-2997");
        set.add("1107-3756");
        set.add("0300-0605");
        set.add("1943-8141");
        set.add("2157-9083");
        set.add("1945-4589");
        set.add("0024-3205");
        set.add("0393-6384");
        set.add("2075-4701");
        set.add("2079-6412");
        set.add("1996-1944");
        set.add("1533-4899");
        set.add("2075-163X");
        set.add("2073-4433");
        set.add("2169-141X");
        set.add("1687-8094");
        set.add("1099-114X");
        set.add("1563-5147");
        set.add("1424-8220");
        set.add("1996-1073");
        set.add("2076-3417");
        set.add("2073-4360");
        set.add("2079-9292");
        set.add("2227-9717");
        set.add("1099-0526");
        set.add("1944-3986");
        set.add("2073-4344");
        set.add("1420-3049");
        set.add("1478-6427");
        set.add("2197-4578");
        set.add("2071-1050");
        set.add("2073-4441");
        set.add("2073-4395");
        set.add("1097-4644");
        set.add("1097-4652");
        set.add("1573-4935");
        set.add("1872-8081");
        set.add("2223-7747");
        set.add("2073-4409");
        set.add("2227-7390");
        set.add("1536-5964");
        set.add("1950-6007");
        set.add("1096-0945");
        set.add("1414-431X");
        set.add("1875-8592");
        set.add("2058-7384");
        set.add("1555-3906");
        set.add("1643-3750");
        set.add("1792-1082");
        set.add("1792-1015");
        set.add("1791-2431");
        set.add("1791-3004");
        set.add("1791-244X");
        set.add("1473-2300");
        set.add("2157-9091");
        set.add("1879-0631");
        set.add("2077-0383");
        set.add("1660-4601");
        set.add("2283-9720");
        set.add("2073-8994");
        set.add("METALS-BASEL");
        set.add("MINERALS-BASEL");
        set.add("ATMOSPHERE-BASEL");
        set.add("SENSORS-BASEL");
        set.add("APPL SCI-BASEL");
        set.add("POLYMERS-BASEL");
        set.add("ELECTRONICS-SWITZ");
        set.add("Z KRIST-NEW CRYST ST");
        set.add("SUSTAINABILITY-BASEL");
        set.add("WATER-SUI");
        set.add("CELLS-BASEL");
        set.add("ADV DIFFER EQU-NY");
        set.add("MATHEMATICS-BASEL");
        set.add("J. NANOSCI. NANOTECHNOL.");
        set.add("ARTIF. CELL. NANOMED. BIOTECHNOL.");
        set.add("ADV. CIV. ENG.");
        set.add("INT. J. ENERGY RES.");
        set.add("MATH. PROBL. ENG.");
        set.add("APPL. SCI.-BASEL");
        set.add("DESALIN. WATER TREAT.");
        set.add("INT. J. ELECTROCHEM. SCI.");
        set.add("NAT. PROD. RES.");
        set.add("Z. KRIST.-NEW CRYST. STRUCT.");
        set.add("J. CELL. BIOCHEM.");
        set.add("J. CELL. PHYSIOL.");
        set.add("BIOSCI. REP.");
        set.add("BIOMED RES. INT.");
        set.add("BOUND. VALUE PROBL.");
        set.add("ADV. DIFFER. EQU.");
        set.add("J. INEQUAL. APPL.");
        set.add("EUR. REV. MED. PHARMACOL. SCI.");
        set.add("INT. J. CLIN. EXP. PATHOL.");
        set.add("INT. J. CLIN. EXP. MED.");
        set.add("BIOMED. PHARMACOTHER.");
        set.add("EXP. MOL. PATHOL.");
        set.add("BRAZILIAN J. MED. BIOL. RES.");
        set.add("CANCER BIOMARK.");
        set.add("INT. J. IMMUNOPATHOL. PHARMACOL.");
        set.add("ONCOL. RES.");
        set.add("AM. J. CANCER RES.");
        set.add("MED. SCI. MONITOR");
        set.add("ONCOL. LETT.");
        set.add("EXP. THER. MED.");
        set.add("ONCOTARGETS THER.");
        set.add("ONCOL. REP.");
        set.add("MOL. MED. REP.");
        set.add("INT. J. MOL. MED.");
        set.add("J. INT. MED. RES.");
        set.add("AM. J. TRANSL. RES.");
        set.add("J. BIOMATER. TISSUE ENG.");
        set.add("LIFE SCI.");
        set.add("J. CLIN. MED.");
        set.add("INT. J. ENVIRON. RES. PUBLIC HEALTH");
        set.add("ACTA MEDICA MEDITERR.");
        return set;
    }

    /*
      CREATE TABLE `csv_wos_talbe` (
        `PT` text,
        `AU` longtext,
        `BA` text,
        `BE` text,
        `GP` text,
        `AF` longtext,
        `BF` text,
        `CA` text,
        `TI` text,
        `SO` text,
        `SE` text,
        `BS` text,
        `LA` text,
        `DT` text,
        `CT` text,
        `CY` text,
        `CL` text,
        `SP` text,
        `HO` text,
        `DE` longtext,
        `ID` text,
        `AB` longtext,
        `C1` longtext,
        `RP` text,
        `EM` text,
        `RI` longtext,
        `OI` longtext,
        `FU` longtext,
        `FX` longtext,
        `CR` longtext,
        `C3` longtext COMMENT '2022.02.21新增字段',
        `WE` longtext COMMENT '2022.02.21新增字段',
        `NR` text,
        `TC` text,
        `Z9` text,
        `u1` text,
        `u2` text,
        `PU` text,
        `PI` text,
        `PA` text,
        `SN` text,
        `EI` text,
        `BN` text,
        `J9` text,
        `JI` text,
        `PD` text,
        `PY` text,
        `VL` text,
        `IS` text,
        `PN` text,
        `SU` text,
        `SI` text,
        `MA` text,
        `BP` text,
        `EP` text,
        `AR` text,
        `DI` text,
        `DL` text COMMENT '2022.08.06新增字段，与DI相似',
        `D2` text,
        `EA` text,
        `PG` text,
        `WC` text,
        `SC` text,
        `GA` text,
        `UT` varchar(25) DEFAULT NULL,
        `PM` varchar(25) DEFAULT NULL,
        `oa` text,
        `hc` text,
        `hp` text,
        `da` text,
        `pid` int(8) NOT NULL AUTO_INCREMENT,
        `FP` longtext,
        `c1_list` longtext,
        `rp_list` longtext,
        `c1_code` int(1) DEFAULT NULL,
        `c1_univ_code` int(1) DEFAULT NULL,
        `c1_hosp_code` int(1) DEFAULT NULL,
        `rp_code` int(1) DEFAULT NULL,
        `rp_univ_code` int(1) DEFAULT NULL,
        `rp_hosp_code` int(1) DEFAULT NULL,
        `univ_name` text,
        `hosp_name` text,
        `hosp_priority` int(1) DEFAULT NULL,
        `datetime` datetime DEFAULT NULL,
        `user_id` int(6) DEFAULT NULL,
        `sort` int(4) DEFAULT NULL,
        `jcr_quartile` int(1) DEFAULT NULL,
        `zky_subject` text,
        `cite_score` double DEFAULT NULL,
        `jcr_if` double DEFAULT NULL,
        `zky_dalei` int(1) DEFAULT NULL,
        `is_early` int(1) DEFAULT NULL,
        PRIMARY KEY (`pid`),
        UNIQUE KEY `UT` (`UT`) USING BTREE,
        KEY `pm` (`PM`(11)) USING BTREE,
        KEY `user_id` (`user_id`),
        KEY `sort` (`sort`),
        KEY `c1_code` (`c1_code`),
        KEY `c1_univ_code` (`c1_univ_code`),
        KEY `c1_hosp_code` (`c1_hosp_code`),
        KEY `rp_code` (`rp_code`),
        KEY `rp_univ_code` (`rp_univ_code`),
        KEY `rp_hosp_code` (`rp_hosp_code`),
        KEY `hosp_priority` (`hosp_priority`),
        KEY `jcr_quartile` (`jcr_quartile`),
        KEY `cite_score` (`cite_score`),
        KEY `jcr_if` (`jcr_if`),
        KEY `zky_dalei` (`zky_dalei`),
        KEY `is_early` (`is_early`)
      ) ENGINE=MyISAM CHARSET=utf8mb4;
     */

}
